package com.vinoxm.admin.config;

import lombok.AllArgsConstructor;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices;
import org.springframework.security.oauth2.provider.code.JdbcAuthorizationCodeServices;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;

import javax.sql.DataSource;

@AllArgsConstructor
@EnableAuthorizationServer
@Configuration
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {

    private AuthenticationManager authenticationManager;
    private DataSource dataSource;
    private UserDetailsService authUserService;
    private PasswordEncoder passwordEncoder;
    private DefaultTokenServices tokenServices;
    private ClientDetailsService jdbcClientDetailsService;

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
        // 从数据库中获取 client信息
        clients.withClientDetails(jdbcClientDetailsService);
    }

    // 管理 authCode信息
    // 相关表: oauth_code
    public AuthorizationCodeServices jdbcAuthorizationCodeServices(){
        return new JdbcAuthorizationCodeServices(dataSource);
    }

    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authenticationManager(authenticationManager) // 密码验证管理
                .userDetailsService(authUserService)// 读取验证用户信息
                .authorizationCodeServices(jdbcAuthorizationCodeServices()) // authCode管理
                .tokenServices(tokenServices); // token管理
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
        security.allowFormAuthenticationForClients() // 允许表单认证
                .tokenKeyAccess("permitAll()") // 开启/oauth/token_key 验证端口-无权限
//                .checkTokenAccess("isAuthenticated()") // 开启/oauth/check_token 验证端口-需权限
                .checkTokenAccess("permitAll()") // 开启/oauth/check_token 验证端口-无权限
                .passwordEncoder(passwordEncoder); // 配置BCrypt加密
    }
}
